package com.gjp.shiro;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.gjp.entity.Role;
import com.gjp.entity.User;
import com.gjp.service.RoleService;
import com.gjp.service.UserService;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by gjp on 2017-6-6.
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    /**
     * 身份认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        Logger.getLogger(this.getClass()).info("身份认证方法：MyShiroRealm.doGetAuthenticationInfo()");
        //转换authenticationToken为UsernamePasswordToken
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //获取账号和密码
        String username = token.getUsername();
        //密码是一个char[]数组，要转换一下
        String password = String.valueOf(token.getPassword());
        // ..... 如果需要加密的话，在此处对password进行加密操作
        // ..... 加密
        // ..... 读取数据库
        User user = userService.selectOne(
                new EntityWrapper<User>()
                        .eq("username", username)
                        .eq("password", password)
        );
        // ..... 判断
        // ..... 用户不存在则抛出异常
        if (user == null) {
            throw new AuthenticationException("账号或密码错误!");
        }
        // ..... 根据用户信息情况，决定是否抛出其他异常
        //用户状态为0 表示被锁定
        if ("0".equals(user.getState())) {
            throw new LockedAccountException("该账号已被锁定!");
        }

        // 根据用户情况，构建SimpleAuthenticationInfo并返回
        return new SimpleAuthenticationInfo(username, password, getName());
    }


    /**
     * 权限验证
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Logger.getLogger(this.getClass()).info("权限认证方法：MyShiroRealm.doGetAuthorizationInfo()");
        //从principalCollection中获取登录用户的信息
        Object username = principalCollection.getPrimaryPrincipal();
        //根据用户信息，获取角色权限(查询数据库)
        Set<String> roles = new HashSet<>();
        //获取用户信息
        User user = userService.selectOne(
                new EntityWrapper<User>()
                        .eq("username", username)
        );
        //如果用户存在
        if (user != null) {
            //获取角色信息
            Role role = roleService.selectOne(
                    new EntityWrapper<Role>()
                            .eq("id", user.getRid())
            );
            //如果角色存在，并且权限也不为空，就将权限加入集合
            //否则表示这个人没有权限，集合将为空
            if (role != null && role.getRoleauthority() != null) {
                String[] split = role.getRoleauthority().split(";");
                for (String item : split) {
                    //如果item不为空
                    if (item != null && !"".equals(item)) {
                        roles.add(item);
                    }
                }
            }
        }
        //创建SimpleAuthorizationInfo 设置其roles
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        //返回
        return info;
    }

}
